package com.yunchang.spring.visitor.demo.service;

import com.yunchang.spring.visitor.core.annotation.ReflectiveCache;
import com.yunchang.spring.visitor.core.annotation.ReflectiveMethod;
import com.yunchang.spring.visitor.core.annotation.ReflectiveService;
import com.yunchang.spring.visitor.core.constant.ContentType;
import com.yunchang.spring.visitor.core.paramtype.HeaderParamsMap;
import com.yunchang.spring.visitor.core.paramtype.UrlParamsMap;
import com.yunchang.spring.visitor.demo.model.MyDataType;
import com.yunchang.spring.visitor.demo.model.MyJsonObject;
import org.springframework.http.HttpMethod;

import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 测试Service的接口
 *
 * @auther zachary
 * @date 2018/3/15
 * @time 18:15
 */
@ReflectiveService(value = "service", namespace = "v1")
public interface ITestService {

    /**
     * 反射调用该方法，没有参数
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/m0
     */
    @ReflectiveMethod
    String m0();

    /**
     * 反射调用该方法，参数默认有且只有一个，类型为Map
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/m1?p1=123
     */
    @ReflectiveMethod
    String m1(Map<String, String> params);

    /**
     * 使用别名，反射调用该方法，参数默认有且只有一个，类型为Map
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/alias?p1=123
     */
    @ReflectiveMethod(alias = "alias")
    String m1Alias(Map<String, String> params);

    /**
     * 反射调用该方法，参数自动填充到aa和bb
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/m2?aa=12&bb=23
     */
    @ReflectiveMethod(params = {"aa", "bb"})
    Map m2(final String aa, final Integer bb);


    /**
     * 反射调用该方法，参数自动填充到aa、bb和cc，其中cc为自定义类型
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/m3?aa=12&bb=23&cc=hello,world
     */
    @ReflectiveMethod(params = {"aa", "bb", "cc"})
    Map m3(final String aa, final Integer bb, MyDataType cc);

    /**
     * 全部存在 param不拆分
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/m4?aa=hh&bb=12
     */
    @ReflectiveMethod
    String m4(HeaderParamsMap header, UrlParamsMap url, HttpMethod method, Map params, InputStream stream);

    /**
     * 全部存在 param拆分
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/m5?aa=hh&bb=12&cc=hello
     */
    @ReflectiveMethod(params = {"aa", "bb", "cc"})
    String m5(final String aa, HttpMethod method, HeaderParamsMap header, UrlParamsMap url,
              final Integer bb, InputStream stream, final String cc);

    /**
     * 无法反射调用该方法，因为注解的参数列表和实际方法声明的参数列表不一致。
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/error?aa=123&bb=789
     */
    @ReflectiveMethod(params = {"aa", "bb"})
    String error(String aa, String bb, String cc);

    /**
     * 错误用例
     * params未定义 但是实际参数想拆分
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/error2?aa=hh&bb=12
     */
    @ReflectiveMethod()
    String error2(HeaderParamsMap header, final String aa, final Integer bb);


    /**
     * 反射调用该方法，没有参数【POST json】
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/json0
     * 内容无
     */
    @ReflectiveMethod(contentType = ContentType.JSON)
    String json0();

    /**
     * 反射调用该方法，参数默认有且只有一个，类型为String【POST json】
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/json1
     * 内容：{"aa":"12","bb":23}
     */
    @ReflectiveMethod(contentType = ContentType.JSON)
    String json1(String json);

    /**
     * 反射调用该方法，参数默认有且只有一个，类型为String【POST json】
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/json2
     * 内容：{"aa":"12","bb":23}
     */
    @ReflectiveMethod(contentType = ContentType.JSON)
    Map json2(Map jsonMap);

    /**
     * 反射调用该方法，参数类型全部存在【POST json】
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/json3
     * 内容：{"aa":"12","bb":23}
     */
    @ReflectiveMethod(contentType = ContentType.JSON)
    String json3(HttpMethod method, HeaderParamsMap header, String json, UrlParamsMap url);

    /**
     * 反射调用该方法，除了String，参数类型全部存在【POST json】
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/json4
     * 内容：{"aa":"12","bb":23}
     */
    @ReflectiveMethod(contentType = ContentType.JSON)
    String json4(HttpMethod method, HeaderParamsMap header, UrlParamsMap url);

    /**
     * 反射调用该方法，参数自动填充到aa、bb和cc，其中cc为自定义类型
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/json5
     * 内容：{"aa":"12","bb":23,"cc":{"id":"","list":[{"name":"name1","value":"xxxx"},{"name":"name2","value":"yyyy"}]}}
     */
    @ReflectiveMethod(contentType = ContentType.JSON, params = {"aa", "bb", "cc"})
    Map json5(HttpMethod method, final String aa, HeaderParamsMap header,
              final Integer bb, UrlParamsMap url, MyJsonObject cc);

    /**
     * 无法反射调用该方法，不允许InputStream类型参数【POST json】
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/json5
     * 内容：{"aa":"12","bb":23}
     */
    @ReflectiveMethod(contentType = ContentType.JSON)
    String jsonError(HttpMethod method, HeaderParamsMap header, String json, UrlParamsMap url, InputStream inputStream);

    /**
     * 反射调用该方法，并缓存方法返回结果，下次用同样参数调用该方法，优先查询缓存。
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/cache?cc=111&dd=2222
     */
    @ReflectiveMethod(params = {"cc", "dd"})
    @ReflectiveCache(unit = TimeUnit.SECONDS, expire = 5)
    Map cache(final String cc, final int dd);

    /**
     * 反射调用该方法，并缓存方法返回结果，下次用同样参数调用该方法，优先查询缓存。【POST json】
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/jsonCache1
     * 内容：{"aa":"12","bb":23}
     */
    @ReflectiveMethod(contentType = ContentType.JSON)
    @ReflectiveCache(unit = TimeUnit.SECONDS, expire = 5)
    Map jsonCache1(String json);

    /**
     * 反射调用该方法，并缓存方法返回结果，下次用同样参数调用该方法，优先查询缓存。【POST json】
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/jsonCache2
     * 内容：{"cc":"12","dd":44}
     */
    @ReflectiveMethod(contentType = ContentType.JSON, params = {"cc", "dd"})
    @ReflectiveCache(unit = TimeUnit.SECONDS, expire = 5)
    Map jsonCache2(final String cc, final int dd);
}
